package com.pfzy.ui.activity.voice;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.util.Log;

import com.pfzy.ui.utils.CommonUtil;

import java.io.IOException;

public class AudioRecorder {
    private static AudioRecorder AudioRecorder;
    private Recorder mRecorder;

    public static AudioRecorder getInstance() {
        if (AudioRecorder == null) {
            AudioRecorder = new AudioRecorder();
        }
        return AudioRecorder;
    }

    public boolean isRecording() {
        return this.mRecorder != null && this.mRecorder.state() == Recorder.RECORDING_STATE;
    }

    public void start(String path) {
        if (this.mRecorder == null) {
            this.mRecorder = new Recorder();
        }
        this.mRecorder.startRecording(path);
    }

    public void stop() {
        if (this.mRecorder != null) {
            this.mRecorder.stopRecording();
        }
    }

    public int getMaxAmplitude() {
        return this.mRecorder.getMaxAmplitude();
    }

    public static class Recorder {
        public static final int IDLE_STATE = 0;
        public static final int RECORDING_STATE = 1;
        public static final int FINISH_STATE = 2;
        public static final int NO_ERROR = 0;
        public static final int SDCARD_ACCESS_ERROR = 1;
        public static final int INTERNAL_ERROR = 2;
        public static final int IN_CALL_RECORD_ERROR = 3;
        private int mState = 0;
        private OnStateChangedListener mOnStateChangedListener = null;
        private MediaRecorder mRecorder = null;

        public interface OnStateChangedListener {
            void onError(int error);

            void onStateChanged(int state);
        }

        public int getMaxAmplitude() {
            if (this.mState != RECORDING_STATE) {
                return IDLE_STATE;
            }
            return this.mRecorder.getMaxAmplitude();
        }

        public void setOnStateChangedListener(OnStateChangedListener listener) {
            this.mOnStateChangedListener = listener;
        }

        public int state() {
            return this.mState;
        }

        public void startRecording(String path) {
            boolean isInCall = true;
            stopRecording();
            this.mRecorder = new MediaRecorder();
            this.mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            this.mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            this.mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            this.mRecorder.setAudioSamplingRate(44100);// 设置录制的音频采样率
            this.mRecorder.setAudioEncodingBitRate(15600);// 设置录制的音频编码比特率
            this.mRecorder.setOutputFile(path);
            try {
                this.mRecorder.prepare();
                this.mRecorder.start();
                setState(RECORDING_STATE);
            } catch (RuntimeException e) {
                AudioManager audioMngr = (AudioManager) CommonUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
                if (audioMngr.getMode() != AudioManager.MODE_IN_CALL && audioMngr.getMode() != AudioManager.MODE_IN_COMMUNICATION) {
                    isInCall = false;
                }
                if (isInCall) {
                    setError(IN_CALL_RECORD_ERROR);
                } else {
                    setError(INTERNAL_ERROR);
                }
                this.mRecorder.reset();
                this.mRecorder.release();
                this.mRecorder = null;
            } catch (IOException e) {
                setError(INTERNAL_ERROR);
                this.mRecorder.reset();
                this.mRecorder.release();
                this.mRecorder = null;
            }
        }

        public void stopRecording() {
            if (this.mRecorder != null) {
                try {
                    this.mRecorder.stop();
                } catch (RuntimeException e) {
                    Log.d("Recorder", "Catch RuntimeException on MediaRecorder.stop() due to a call immediately after MediaRecorder.start().");
                }
                this.mRecorder.release();
                this.mRecorder = null;
                setState(FINISH_STATE);
            }
        }

        private void setState(int state) {
            if (state != this.mState) {
                this.mState = state;
                signalStateChanged(this.mState);
            }
        }

        /**
         * 信号状态已更改
         *
         * @param state
         */
        private void signalStateChanged(int state) {
            if (this.mOnStateChangedListener != null) {
                this.mOnStateChangedListener.onStateChanged(state);
            }
        }

        private void setError(int error) {
            if (this.mOnStateChangedListener != null) {
                this.mOnStateChangedListener.onError(error);
            }
        }
    }
}
